#!/usr/bin/python
#coding=utf-8

'''
Importing a Dynamically Generated Module
https://www.oreilly.com/library/view/python-cookbook/0596001673/ch15s03.html
'''
import imp
import uuid
import sys

def importCode(_src, code, add_to_sys_modules=False):
    """ code can be any object containing code -- string, file object, or
       compiled code object. Returns a new module object initialized
       by dynamically importing the given code and optionally adds it
       to sys.modules under the given name.
    """
    name = str(uuid.uuid1())
    module = imp.new_module(name)

    if add_to_sys_modules:
        sys.modules[name] = module

    try:
        module.__dict__.update({'_src':_src})
        exec(code, module.__dict__)
    except NameError as exc:
        return None, 'ERROR:{text}'.format(text=str(exc))
    except (BaseException) as exc:
        ''' exc中主要字段：
        filename = {str} '<string>'
        lineno = {int} 4
        msg = {str} 'invalid syntax'
        offset = {int} 9
        print_file_and_line = {NoneType} None
        text = {str} '        ><f() > 1 and df["code"] > "1"\n'
        '''
        return None, 'ERROR:【行:{lineno}列:{offset}, 错误:{msg}】{text}'.format(lineno=exc.lineno,
                  offset=exc.offset, msg=exc.msg, text=exc.text)

    return module, ''


def checkCode(_src, code, lineno=0):
    name = str(uuid.uuid1())
    module = imp.new_module(name)

    try:
        module.__dict__.update({'_src':_src})
        exec(code, module.__dict__)
    except NameError as exc:
        return 1, 'ERROR:{text}'.format(text=str(exc))
    except (BaseException) as exc:
        ''' exc中主要字段：
        filename = {str} '<string>'
        lineno = {int} 4
        msg = {str} 'invalid syntax'
        offset = {int} 9
        print_file_and_line = {NoneType} None
        text = {str} '        ><f() > 1 and df["code"] > "1"\n'
        '''
        return 1, 'ERROR:【行:{lineno}列:{offset}, 错误:{msg}】{text}'.format(lineno=exc.lineno-lineno,
                  offset=exc.offset, msg=exc.msg, text=exc.text)

    return 0, ''

def sr_CheckCode(_src, code):
    str0 = '''import CommonUtils as cu
def test__(df):
    '''
    code_ = '\n    '.join(('\n'+code).split('\n'))
    str0 += code_

    return checkCode(_src, str0, 3)



if __name__ == '__main__':
    code = """
def testFunc():
    print ("spam!")

class testClass:
    def testMethod(self):
        print ("eggs!")
    """
    '''
    m = importCode(code)
    m.testFunc()
    o = m.testClass()
    o.testMethod()
    '''
    status, s = sr_CheckCode(None, '><f() > 1 and df["code"] > "1"')
    if (status == 0):
        print ('correct code')
    else:
        print ('checkCode(): ' + s)

'''
1 str = "for i in range(0,10): print i"
2 c = compile(str,'','exec')      # 编译为字节代码对象
3 exec c                          # 执行
4
5 str2 = "3*x + 4*y"
6 c2 = compile(str2, '', 'eval')  # 编译为表达
'''
